1 Descripción del dataset

El conjunto de datos del titanic es ampliamente concido en la comunidad del ML. Es más, forma parte de los retos de iniciación en la plataforma kaggle.

Este conjunto de datos, es la representación de las personas que embarcaron en el titanic. En el, se recogen multitud de datos sobre cada persona, relativos a su edad, pais y clase en la que embarcaron, además de si sobrevivieron o no.

1.1 ¿Por qué es importante?

Este cojunto de datos tiene la posibilidad de explicar algunos datos de la catastrofe. Puede aclarar si hubo algún condicionante para la muerte o supervivencia de las personas más allá del puro azar.

1.2 ¿Qué pregunta pretende responder?

Este cojunto de datos pretende elaborar un modelo predictivo y con el responder a la pregunta: ¿Qué tipo de personas tenían más probabilidades de sobrevivir?

2 Integración de los datos de interés a analizar

Antes de integrar, vamos a describir las variables que caracterízan a estos datos:

Escogemos las columnas que serán factores:

factors = c("Sex"="factor","Pclass"="factor","Cabin"="factor", "Embarked"="factor","SibSp"="factor","Parch"="factor","Survived"="factor");

Cargamos los datos:

titanicData <- read.csv('titanic.csv', stringsAsFactors = FALSE, colClasses = factors );
summary(titanicData);
##   PassengerId    Survived Pclass      Name               Sex     
##  Min.   :  1.0   0:549    1:216   Length:891         female:314  
##  1st Qu.:223.5   1:342    2:184   Class :character   male  :577  
##  Median :446.0            3:491   Mode  :character               
##  Mean   :446.0                                                   
##  3rd Qu.:668.5                                                   
##  Max.   :891.0                                                   
##                                                                  
##       Age        SibSp   Parch      Ticket               Fare       
##  Min.   : 0.42   0:608   0:678   Length:891         Min.   :  0.00  
##  1st Qu.:20.12   1:209   1:118   Class :character   1st Qu.:  7.91  
##  Median :28.00   2: 28   2: 80   Mode  :character   Median : 14.45  
##  Mean   :29.70   3: 16   3:  5                      Mean   : 32.20  
##  3rd Qu.:38.00   4: 18   4:  4                      3rd Qu.: 31.00  
##  Max.   :80.00   5:  5   5:  5                      Max.   :512.33  
##  NA's   :177     8:  7   6:  1                                      
##          Cabin     Embarked
##             :687    :  2   
##  B96 B98    :  4   C:168   
##  C23 C25 C27:  4   Q: 77   
##  G6         :  4   S:644   
##  C22 C26    :  3           
##  D          :  3           
##  (Other)    :186

Los datos de interés de ese cojunto de datos serán los que nos aporten algo de información sobre las personas pero a nivel de cojunto, es decir datos como nombre, identificador de pasajero o número de ticket no nos resultan de utilidad. Por lo que podemos crear un conjunto de datos solamente con los datos adecuados:

cols_remove <- c("PassengerId", "Name", "Ticket")
titanicData <- titanicData[, !(colnames(titanicData) %in% cols_remove)]
summary(titanicData);
##  Survived Pclass      Sex           Age        SibSp   Parch        Fare       
##  0:549    1:216   female:314   Min.   : 0.42   0:608   0:678   Min.   :  0.00  
##  1:342    2:184   male  :577   1st Qu.:20.12   1:209   1:118   1st Qu.:  7.91  
##           3:491                Median :28.00   2: 28   2: 80   Median : 14.45  
##                                Mean   :29.70   3: 16   3:  5   Mean   : 32.20  
##                                3rd Qu.:38.00   4: 18   4:  4   3rd Qu.: 31.00  
##                                Max.   :80.00   5:  5   5:  5   Max.   :512.33  
##                                NA's   :177     8:  7   6:  1                   
##          Cabin     Embarked
##             :687    :  2   
##  B96 B98    :  4   C:168   
##  C23 C25 C27:  4   Q: 77   
##  G6         :  4   S:644   
##  C22 C26    :  3           
##  D          :  3           
##  (Other)    :186

3 Limpieza de los datos.

3.1 ¿Los datos contienen ceros o elementos vacíos? ¿Cómo gestionarías cada uno de estos casos?

Para comprobar si los datos contienen elementos vacíos se ejecuta la siguiente sentencia.

colSums(is.na(titanicData))
## Survived   Pclass      Sex      Age    SibSp    Parch     Fare    Cabin 
##        0        0        0      177        0        0        0        0 
## Embarked 
##        0

Se puede observar que la columna Age contiene 177 valores nulos. Existen diferentes políticas para el tratamiento de los valores nulos:

  • Eliminarlos: En Ocasiones, compensa eliminar estas filas, ya que pueden generar distorsiones a la hora de hacer cálculos con las columnas que contienen los valores nulos.

  • Reemplazo: Se podrían reemplazar los valores por la media, la mediana o la moda. Estas medidas se pueden intentar particular en función de otras columnas para que no siempre sean los mismos para todas las entradas nulas.

  • Asignación de una categoría: Si se discretizan los datos en, por ejemplo, rangos de edad, se puede particularizar todos los valores nulos en una categoría especial llamada “edad desconocida”.

  • Predicción de los valores nulos: Por último, se pueden inferir los valores mediante predicciones.

En este caso, se van a inferir los valores en función de otros parámentros. Para hacer esto, partimos de que es muy probable que la edad media de las personas que viajan en Pclass3 es diferente a la edad media de las personas que viajan en Pclass1. Además, esa edad será diferente en función de si estamos ante un hombre o una mujer. Por tanto, para inferir los valores de edad perdidos, se agrupa por Sex y Pclass, para posteriormente calcular las medianas de cada serie agrupada.

Primero, se calcula la media y la mediana de edad en función de la clase y el género del pasajero.

by_sex_class <- titanicData %>% group_by(Sex, Pclass)  %>% summarise(mean = mean(Age, na.rm = TRUE), median = median(Age, na.rm = TRUE))
                      
by_sex_class
## # A tibble: 6 x 4
## # Groups:   Sex [2]
##   Sex    Pclass  mean median
##   <fct>  <fct>  <dbl>  <dbl>
## 1 female 1       34.6   35  
## 2 female 2       28.7   28  
## 3 female 3       21.8   21.5
## 4 male   1       41.3   40  
## 5 male   2       30.7   30  
## 6 male   3       26.5   25

Se observa que la media y la mediana de edad varía en función del género y la clase en la que viajaban. Se procede a rellenar los valores nulos en la columna de edad por los valores de mediana en función de Sex y Pclass.

titanicData$Age[titanicData$Sex == "female" & titanicData$Pclass == "1" & is.na(titanicData$Age)] <- by_sex_class$median[by_sex_class$Sex == "female" & by_sex_class$Pclass == "1"]

titanicData$Age[titanicData$Sex == "female" & titanicData$Pclass == "2" & is.na(titanicData$Age)] <- by_sex_class$median[by_sex_class$Sex == "female" & by_sex_class$Pclass == "2"]

titanicData$Age[titanicData$Sex == "female" & titanicData$Pclass == "3" & is.na(titanicData$Age)] <- by_sex_class$median[by_sex_class$Sex == "female" & by_sex_class$Pclass == "3"]

titanicData$Age[titanicData$Sex == "male" & titanicData$Pclass == "1" & is.na(titanicData$Age)] <- by_sex_class$median[by_sex_class$Sex == "male" & by_sex_class$Pclass == "1"]

titanicData$Age[titanicData$Sex == "male" & titanicData$Pclass == "2" & is.na(titanicData$Age)] <- by_sex_class$median[by_sex_class$Sex == "male" & by_sex_class$Pclass == "2"]

titanicData$Age[titanicData$Sex == "male" & titanicData$Pclass == "3" & is.na(titanicData$Age)] <- by_sex_class$median[by_sex_class$Sex == "male" & by_sex_class$Pclass == "3"]

Se vuelve a comprobar si existen valores nulos.

colSums(is.na(titanicData))
## Survived   Pclass      Sex      Age    SibSp    Parch     Fare    Cabin 
##        0        0        0        0        0        0        0        0 
## Embarked 
##        0

Se han eliminado los valores nulos. Ahora, se comprueba que el summary no difiere mucho del original.

summary(titanicData)
##  Survived Pclass      Sex           Age        SibSp   Parch        Fare       
##  0:549    1:216   female:314   Min.   : 0.42   0:608   0:678   Min.   :  0.00  
##  1:342    2:184   male  :577   1st Qu.:21.50   1:209   1:118   1st Qu.:  7.91  
##           3:491                Median :26.00   2: 28   2: 80   Median : 14.45  
##                                Mean   :29.11   3: 16   3:  5   Mean   : 32.20  
##                                3rd Qu.:36.00   4: 18   4:  4   3rd Qu.: 31.00  
##                                Max.   :80.00   5:  5   5:  5   Max.   :512.33  
##                                                8:  7   6:  1                   
##          Cabin     Embarked
##             :687    :  2   
##  B96 B98    :  4   C:168   
##  C23 C25 C27:  4   Q: 77   
##  G6         :  4   S:644   
##  C22 C26    :  3           
##  D          :  3           
##  (Other)    :186

La media de edad ha bajado ligeramente, pero en general los datos se mantienen estables aún habiendo inferido 177 entradas.